﻿using System;
using System.Linq;
using System.Reflection;
using QuickPrompt.DomainModel.Identity;
using QuickPromt.Service;
using RedandBlue.Common.Authorization;
using RedandBlue.Common.Logging;
using RedandBlue.Common.Track;
using RedandBlue.RepositoryPattern.Repositories;
using RedandBlue.RepositoryService;

namespace QuickPrompt.BusinessService
{
    public class UserService : Service<User>, IUserService
    {
        private readonly IRepositoryAsync<User> _repository;

        public UserService(IRepositoryAsync<User> repository)
            : base(repository)
        {
            _repository = repository;
        }

        public override void Insert(User entity)
        {
            Password password = new Password();
            string passwordSalt = password.GenerateSalt();
            entity.PasswordHash = password.EncodeToHash(entity.Password, passwordSalt);
            entity.PasswordSalt = passwordSalt;
            // e.g. add business logic here before inserting
            base.Insert(entity);
        }

        public override void Delete(object id)
        {
            // e.g. add business logic here before deleting
            base.Delete(id);
        }

        public bool Login(string userName, string password)
        {
            string userId = ValidatePassword(userName, password);
            return !string.IsNullOrEmpty(userId);
        }

        public bool Create(User user)
        {
            var password = new Password();
            var salt = password.GenerateSalt();
            user.PasswordSalt = salt;
            user.PasswordHash = password.EncodeToHash(user.Password, salt);
            try
            {
                base.Insert(user);
                return true;
            }
            catch (Exception exception)
            {
                Log.Error(GetType().FullName, MethodBase.GetCurrentMethod().Name, exception);
                return false;
            }
        }

        private string ValidatePassword(string userName, string password)
        {
                var user = _repository.Query(x => x.UserName.Equals(userName, StringComparison.OrdinalIgnoreCase))
                    .Select().FirstOrDefault();

            if (user == null)
                return null;

            string userId = ValidatePassword(user, password) ? user.Id : null;

            user.LastUpdatedUtc = DateTime.UtcNow;
            user.LastActivityIpAddress = ClientEnvironment.GetClientIp();
            _repository.Update(user);
            return userId;
        }

        private static bool ValidatePassword(User user, string password)
        {
            return user.PasswordHash == new Password().EncodeToHash(password, user.PasswordSalt);
        }

    }
}
